package cate.game.role.bag.newtalent;


import cate.common.table.d.GDHeroTalent;
import cate.common.table.d.GDObj;
import cate.common.table.fight.skill.row.SkillBaseRow;
import cate.common.table.item.hero.row.HeroTalentRow;
import cate.common.util.GameResult;
import cate.game.event.hero.HeroPowerChangeEvent;
import cate.game.play.support.PlayBuildContext;
import cate.game.res.MixRes;
import cate.game.res.MixResItem;
import cate.game.role.Role;
import cate.game.role.RoleDependent;
import cate.game.role.bag.hero.Hero;
import com.fasterxml.jackson.annotation.JsonIgnore;
import cp.solution.util.collection.ListKit;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.annotation.Transient;

import java.util.ArrayList;
import java.util.List;

public class NewTalentOn extends RoleDependent {
    @JsonIgnore
    @Transient
    public transient Hero owner;

    @NoteField("天赋列表")
    public List<TalentItem> list;

    public void initialize(Hero hero, Role role) {
        super.initialize(role);
        this.owner = hero;
        if (list == null) {
            list = new ArrayList<>();
        }
    }

    @JsonIgnore
    public TalentItem getTalentByPos(int pos) {
        for (TalentItem item : list) {
            if (item.pos == pos) {
                return item;
            }
        }
        return null;
    }

    /**
     * 获取 PowerAttrPart
     */
    @JsonIgnore
    public TalentsOnPAP getPowerAttrPart(PlayBuildContext ctx) {
        return new TalentsOnPAP(ctx, this);
    }

    /**
     * 查找天赋
     */
    @JsonIgnore
    private TalentItem getItem(String talentIdHex) {
        for (TalentItem item : list) {
            if (StringUtils.equals(talentIdHex, item.uid)) {
                return item;
            }
        }
        return null;
    }

    private GameResult<TalentItem> getItemResult(String talentIdHex) {
        GameResult<TalentItem> r = new GameResult<>();
        TalentItem item = getItem(talentIdHex);
        if (item == null) {
            return r.fail("你还没有该天赋");
        }
        HeroTalentRow tpl = item.getTpl(role.getGame().fight.getPlayBuildContext());
        if (tpl == null) {
            return r.fail("天赋模板配置不存在");
        }
        r.data = item;
        return r.success();
    }

    /**
     * 新增天赋【即：领悟天赋】
     */
    public GameResult<TalentItem> addItem(int talentTid, int pos) {
        GameResult<TalentItem> r = new GameResult<>();
        boolean avaible = GDHeroTalent.POS.checkPos(pos);
        if (!avaible) {
            return r.fail("栏位不存在");
        }
        TalentItem talent = getTalentByPos(pos);
        if (talent != null) {
            return r.fail("该栏位已经有天赋");
        }
        if (owner.getTpl(role.getGame().fight.getPlayBuildContext()).star < GDHeroTalent.getStarRequiredByPos(pos)) {
            return r.fail("栏位未解锁");
        }
        HeroTalentRow tpl = getRow(talentTid);
        if (tpl == null) {
            return r.fail("天赋模板配置不存在");
        }
        if (tpl.level > 1) {
            return r.fail( "不可直接学习高等级天赋");
        }
        // 根据技能原型ID检测是不是重复的天赋
        for (TalentItem item : this.list) {
            if (item.getTpl(role.getGame().fight.getPlayBuildContext()).protoId == tpl.protoId) {
                return r.fail("不可领悟同一种天赋");
            }
        }
        MixRes res = new MixRes(tpl.costStr);
        EcResult<MixResItem> costRes = res.consume(role, null);
        if (!costRes.ok()) {
            role.getGame().notice.tipResItem(role, costRes.data);
            return r.fail(costRes);
        }
        TalentItem item = new TalentItem(talentTid, pos);
        this.list.add(item);
        r.data = item;
        role.getBase().updatePower();
        role.getHistory().action.teamTalentLevel();
        return r.success();
    }

    /**
     * 天赋升级
     */
    public GameResult<TalentItem> upgradeItem(String talentIdHex) {
        GameResult<TalentItem> r = getItemResult(talentIdHex);
        if (!r.ok()) {
            return r;
        }
        TalentItem item = r.data;
        if (item.getTpl(role.getGame().fight.getPlayBuildContext()).top) {
            return r.fail("已经升到最高级");
        }
        HeroTalentRow nextTpl = getRow(item.getTpl(role.getGame().fight.getPlayBuildContext()).nextId);
        if (nextTpl == null) {
            return r.fail("天赋模板配置不存在");
        }
        MixRes cost = new MixRes(nextTpl.costStr);
        EcResult<MixResItem> costRes = cost.consume(role, null);
        if (!costRes.ok()) {
            role.getGame().notice.tipResItem(role, costRes.data);
            return r.fail(costRes);
        }
        item.tid = nextTpl.id;
        r.data = item;
        role.getBase().updatePower();
        role.getHistory().action.teamTalentLevel();
        role.getHistory().action.talentLevelTimes();
        role.getHistory().action.talentLevelUp(nextTpl.level);
        return r.success();
    }

    /**
     * 天赋遗忘
     */
    public GameResult<Void> forgetItem(String talentIdHex) {
        GameResult<Void> r = new GameResult<>();
        GameResult<TalentItem> itemRes = getItemResult(talentIdHex);
        if (!itemRes.ok()) {
            return r.fail(itemRes);
        }
        TalentItem item = itemRes.data;
        MixRes consume = new MixRes();
        consume.addItem(new MixResItem(GDObj.Type.NUM, GDObj.Num.M1, item.getTpl(role.getGame().fight.getPlayBuildContext()).forget_m1));
        GameResult<MixResItem> costRes = consume.consume(role, null);
        if (!costRes.ok()) {
            role.getGame().notice.tipResItem(role, costRes.data);
            return r.fail(costRes);
        }
        MixRes back = new MixRes(item.getTpl(role.getGame().fight.getPlayBuildContext()).backStr);
        GameResult<Void> addRes = back.add(role);
        if (!addRes.ok()) {
            return r.fail(addRes);
        }
        role.getGame().notice.dialogReward(role, back);
        removeItem(list, talentIdHex);
        role.getBase().updatePower();
        publishEvent(role, new HeroPowerChangeEvent(role, owner));
        return r.success();
    }

    private void removeItem(List<TalentItem> list, String talentIdHex) {
        list.removeIf(tItem -> tItem != null && StringUtils.equals(tItem.uid, talentIdHex));
    }

    public NewTalentOn copy() {
        NewTalentOn cp = new NewTalentOn();
        cp.initialize(this.owner, role);
        cp.list = ListKit.cloneList(list, TalentItem::copy);
        return cp;
    }

    private HeroTalentRow getRow(int tid) {
        HeroTalentRow row = role.getGame().table.rune.talent.get(tid);
        if (row == null) {
            return row;
        }
        SkillBaseRow skillBaseRow = role.getGame().table.skill.base.get(row.skillId);
        if (skillBaseRow != null) {
            row.protoId = skillBaseRow.protoId;
        } else {
            row.protoId = row.skillId;
        }
        return row;
    }
}
